<!--
 * @Author: ZAL 2177624751@qq.com
 * @Date: 2025-01-13 15:02:47
 * @LastEditors: ZAL 2177624751@qq.com
 * @LastEditTime: 2025-03-31 10:31:07
 * @FilePath: \asset-management-webc:\Users\21776\Desktop\毕设\shop_app_vue3\pages\classes\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <view class="container">
    <!-- 顶部搜索栏 -->
    <view class="header">
      <SearchBar placeholder="搜索商品" @search="search" />
    </view>

    <view class="content">
      <!-- 左侧分类菜单 -->
      <scroll-view class="category-menu" scroll-y>
        <view
          class="menu-item"
          v-for="(item, index) in categories"
          :key="item.id"
          :class="{ active: active === index }"
          @click="leftClickHandle(index, item)"
        >
          <text>{{ item.title }}</text>
        </view>
      </scroll-view>

      <!-- 右侧商品列表 -->
      <scroll-view class="product-list" scroll-y>
        <!-- 加载状态 -->
        <view v-if="loading.categories" class="loading">
          <uni-load-more status="loading" iconType="circle"></uni-load-more>
          <text>加载中...</text>
        </view>
        
        <!-- 有数据时显示商品列表 -->
        <view v-else-if="currentCategory?.fruits?.length > 0">
          <view class="product-item" v-for="item in currentCategory.fruits" :key="item.id">
            <view class="product-card" @click="openDetail(item)">
              <image :src="item.imageUrl" mode="aspectFill" />
              <view class="info">
                <view class="title">{{ item.name }}</view>
                <view class="specs">
                  <text class="desc">{{ item.description }}</text>
                </view>
                <view class="bottom">
                  <view class="price-wrap">
                    <text class="price">{{ item.price }}</text>
                  </view>
                  <view class="sales">已售{{ item.sales || 0 }}件</view>
                </view>
              </view>
            </view>

            <!-- 加购按钮 -->
            <view class="action-buttons">
              <view class="quantity-controls" v-if="getCartQuantity(item.id) > 0">
                <u-icon
                  name="minus-circle"
                  size="36"
                  color="#00b578"
                  @click.stop="decreaseQuantity(item)"
                />
                <text class="quantity">{{ getCartQuantity(item.id) }}</text>
                <u-icon
                  name="plus-circle"
                  size="36"
                  color="#00b578"
                  @click.stop="increaseQuantity(item)"
                />
              </view>
              <u-icon
                v-else
                name="shopping-cart"
                size="36"
                color="#00b578"
                @click.stop="addToCart(item)"
              />
            </view>
          </view>
        </view>

        <!-- 空状态 -->
        <view v-else class="empty-state">
          <image src="/static/images/empty_shop_car.png" mode="aspectFit" class="empty-image"></image>
          <text>暂无相关商品</text>
        </view>
      </scroll-view>
    </view>
  </view>
</template>

<script setup>
import { ref} from 'vue'
import { storeToRefs } from 'pinia'
import SearchBar from '../../components/SearchBar.vue'
import { useProductStore } from '../../store/productStore'
import { useCartStore } from '../../store/cartStore'
import {onShow} from '@dcloudio/uni-app'

const productStore = useProductStore()
const cartStore = useCartStore()
const { categories, loading } = storeToRefs(productStore)
const { cartList } = storeToRefs(cartStore)
const active = ref(0)
const currentCategory = ref(null)

const fetchCategories = async () => {
  try {
    await productStore.loadCategories()
    if (categories.value.length > 0) {
      currentCategory.value = categories.value[0]
    }
  } catch (error) {
    uni.showToast({
      title: '获取分类失败',
      icon: 'none'
    })
  }
}

const leftClickHandle = (index, category) => {
  active.value = index
  currentCategory.value = category
}

const handleSearch = async (keyword) => {
  if (!keyword) return
  try {
    await productStore.searchProducts(keyword)
  } catch (error) {
    uni.showToast({
      title: '搜索商品失败',
      icon: 'none'
    })
  }
}

const addToCart = async (item) => {
  try {
    const cartDTO = {
      fruitId: item.id,
      quantity: 1,
      selected: 1
    }
    const res = await cartStore.addItemToCart(cartDTO)
    if (res.code === 200) {
      uni.showToast({
        title: '已加入购物车',
        icon: 'success'
      })
      await cartStore.updateCartInfo()
    }
  } catch (error) {
    uni.showToast({
      title: '添加购物车失败',
      icon: 'none'
    })
  }
}

const increaseQuantity = async (item) => {
  try {
    const cartItem = cartStore.cartList.find(cart => Number(cart.fruitId) === Number(item.id))
    if (cartItem) {
      await cartStore.deleteCartItem(Number(cartItem.id))
      
      const cartDTO = {
        fruitId: Number(item.id),
        quantity: cartItem.quantity + 1,
        selected: cartItem.selected
      }
      
      const res = await cartStore.addItemToCart(cartDTO)
      if (res.code === 200) {
        uni.showToast({
          title: '数量已增加',
          icon: 'success'
        })
        await cartStore.updateCartInfo()
      }
    } else {
      await addToCart(item)
    }
  } catch (error) {
    uni.showToast({
      title: '增加数量失败',
      icon: 'none'
    })
  }
}

const decreaseQuantity = async (item) => {
  try {
    const cartItem = cartStore.cartList.find(cart => Number(cart.fruitId) === Number(item.id))
    if (cartItem) {
      if (cartItem.quantity > 1) {
        await cartStore.deleteCartItem(Number(cartItem.id))
        
        const cartDTO = {
          fruitId: Number(item.id),
          quantity: cartItem.quantity - 1,
          selected: cartItem.selected
        }
        
        const res = await cartStore.addItemToCart(cartDTO)
        if (res.code === 200) {
          uni.showToast({
            title: '数量已减少',
            icon: 'success'
          })
          await cartStore.updateCartInfo()
        }
      } else {
        const cartId = Number(cartItem.id)
        const res = await cartStore.deleteCartItem(cartId)
        if (res.code === 200) {
          uni.showToast({
            title: '商品已移除',
            icon: 'success'
          })
          await cartStore.updateCartInfo()
        }
      }
    }
  } catch (error) {
    uni.showToast({
      title: '减少数量失败',
      icon: 'none'
    })
  }
}

const search = (event) => {
  handleSearch(event.detail)
}

const openDetail = (item) => {
  if (!item || !item.id) {
    uni.showToast({
      title: '商品信息不完整',
      icon: 'none'
    })
    return
  }
  uni.navigateTo({
    url: `/pages/classes/components/product-detail?detailId=${item.id}`
  })
}

const getCartQuantity = (fruitId) => {
  const cartItem = cartList.value.find(item => item.fruitId == fruitId)
  return cartItem ? cartItem.quantity : 0
}

onShow(() => {
  fetchCategories()
})
</script>

<style lang="scss" scoped>
.container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: $bg-color;
}

.header {
  background: linear-gradient(to right, #00b578, #07c160);
  padding: $spacing-sm;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

.content {
  margin-top: 135rpx;
  flex: 1;
  display: flex;
  overflow: hidden;
}

.category-menu {
  width: 180rpx;
  min-width: 180rpx;
  height: 100%;
  background-color: $bg-color-light;
  flex-shrink: 0;

  .menu-item {
    height: 90rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    font-size: 28rpx;
    color: $text-color-secondary;
    padding: 0 12rpx;
    text-align: center;

    &.active {
      color: #00b578;
      background-color: $bg-color-white;
      font-weight: bold;

      &::before {
        content: '';
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 6rpx;
        height: 36rpx;
        background-color: #00b578;
        border-radius: 0 4rpx 4rpx 0;
      }
    }
  }
}

.product-list {
  flex: 1;
  height: 100%;
  padding: 16rpx;
  background-color: $bg-color;

  .product-item {
    margin-bottom: 20rpx;
    background-color: $bg-color-white;
    border-radius: 12rpx;
    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
    position: relative;
    overflow: hidden;
    padding-bottom: 60rpx;

    .product-card {
      display: flex;
      padding: 20rpx;
      min-height: 200rpx;

      image {
        width: 160rpx;
        height: 160rpx;
        border-radius: 8rpx;
        margin-right: 16rpx;
        object-fit: cover;
      }

      .info {
        flex: 1;
        display: flex;
        flex-direction: column;
        justify-content: flex-start;

        .title {
          font-size: 30rpx;
          font-weight: bold;
          color: $text-color;
          margin-bottom: 8rpx;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }

        .specs {
          margin: 8rpx 0;
          display: flex;
          flex-direction: column;
          align-items: flex-start;

          .unit {
            font-size: 24rpx;
            color: $text-color-secondary;
            background-color: $bg-color-light;
            padding: 2rpx 10rpx;
            border-radius: 4rpx;
            margin-bottom: 6rpx;
            display: inline-block;
          }

          .desc {
            font-size: 24rpx;
            color: $text-color-light;
            width: 100%;
            white-space: normal;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 4;
            -webkit-box-orient: vertical;
            word-break: break-all;
            line-height: 1.4;
          }
        }

        .bottom {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-top: 10rpx;

          .price-wrap {
            .symbol {
              font-size: 24rpx;
              color: $warning-color;
            }

            .price {
              font-size: 32rpx;
              font-weight: bold;
              color: #ff8800;
            }
          }

          .sales {
            font-size: 22rpx;
            color: $text-color-light;
          }
        }
      }
    }

    .action-buttons {
      position: absolute;
      right: 20rpx;
      bottom: 16rpx;
      z-index: 2;

      .quantity-controls {
        display: flex;
        align-items: center;
        gap: 10rpx;

        .quantity {
          font-size: 28rpx;
          color: $text-color;
          min-width: 40rpx;
          text-align: center;
        }
      }

      u-icon {
        color: #00b578;
      }
    }
  }
}

.empty-state {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: 30rpx;

  text {
    font-size: 28rpx;
    color: $text-color-light;
    margin-top: 20rpx;
  }
}

.loading {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  
  text {
    font-size: 28rpx;
    color: $text-color-light;
    margin-top: 20rpx;
  }
}

.empty-image {
  width: 200rpx;
  height: 200rpx;
  margin-bottom: 20rpx;
}
</style>
